package net.penguinmenac3.math;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

import net.penguinmenac3.math.rings.ComplexNumber;
import net.penguinmenac3.math.rings.RealNumber;

public class Terminal {
	public static void main(String[] args) throws IOException {
		String cmd = "";
		String temp = "";
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		while (!cmd.equals("yes")) {
			for (int i = 0; i < 50; i++) {
				System.out.println();
			}
			System.out.println("******************************");
			System.out.println("Matrix solver by penguinmenac3");
			System.out.println("******************************");
			System.out.println();
			System.out.println("(supports real numbers atm)");
			System.out.println();
			System.out.println("New Calculation:");
			int rows = -1;
			int columns = -1;
			while (rows < 1 || rows > 20) {
				System.out.print("Rows (0,20]> ");
				System.out.flush();
				temp = in.readLine();
				rows = Integer.parseInt(temp);
			}
			while (columns < 1 || columns > 20) {
				System.out.print("Columns (0,20]> ");
				System.out.flush();
				temp = in.readLine();
				columns = Integer.parseInt(temp);
			}

			MathObject[][] mathObjs = new MathObject[rows][columns];
			for (int i = 0; i < rows; i++) {
				for (int j = 0; j < columns; j++) {
					while (mathObjs[i][j] == null) {
						System.out.print("(" + i + "," + j
								+ ") Complex (a+bi)> ");
						System.out.flush();
						temp = in.readLine();
						if (temp.contains("i")) {
							temp = temp.replaceAll(" ", "");
							StringTokenizer st = new StringTokenizer(temp, "+");
							String first = "";
							String second = "";
							if (st.hasMoreTokens()) {
								first = st.nextToken();
							} else {
								System.out.println("Invalid Input");
								continue;
							}
							if (st.hasMoreTokens()) {
								second = st.nextToken();
							} else {
								second = first;
								first = "0.0";
							}
							if (st.hasMoreTokens()) {
								System.out.println("Invalid Input");
								continue;
							}
							second = second.replaceFirst("i", "");
							double re;
							double im;
							try {
								re = Double.parseDouble(first);
							} catch (NumberFormatException e) {
								System.out.println("Invalid Input");
								continue;
							}
							try {
								im = Double.parseDouble(second);
							} catch (NumberFormatException e) {
								System.out.println("Invalid Input");
								continue;
							}
							mathObjs[i][j] = new ComplexNumber(re, im);
						} else {
							double d;
							try {
								d = Double.parseDouble(temp);
							} catch (NumberFormatException e) {
								System.out.println("Invalid Input");
								continue;
							}
							mathObjs[i][j] = new ComplexNumber(d, 0);
						}
					}
				}
			}

			System.out.print("Extended? 'yes'> ");
			System.out.flush();
			temp = in.readLine();
			Matrix matrix = null;
			if (temp.equals("yes")) {
				columns = -1;
				while (columns < 0 || columns > 20) {
					System.out.print("Columns (0,20)> ");
					System.out.flush();
					temp = in.readLine();
					columns = Integer.parseInt(temp);
				}

				MathObject[][] mathObjs2 = new MathObject[rows][columns];
				for (int i = 0; i < rows; i++) {
					for (int j = 0; j < columns; j++) {
						while (mathObjs2[i][j] == null) {
							System.out.print("(" + i + "," + j
									+ ") Complex (a+bi)> ");
							System.out.flush();
							temp = in.readLine();
							if (temp.contains("i")) {
								temp = temp.replaceAll(" ", "");
								StringTokenizer st = new StringTokenizer(temp,
										"+");
								String first = "";
								String second = "";
								if (st.hasMoreTokens()) {
									first = st.nextToken();
								} else {
									System.out.println("Invalid Input");
									continue;
								}
								if (st.hasMoreTokens()) {
									second = st.nextToken();
								} else {
									second = first;
									first = "0.0";
								}
								if (st.hasMoreTokens()) {
									System.out.println("Invalid Input");
									continue;
								}
								second = second.replaceFirst("i", "");
								double re;
								double im;
								try {
									re = Double.parseDouble(first);
								} catch (NumberFormatException e) {
									System.out.println("Invalid Input");
									continue;
								}
								try {
									im = Double.parseDouble(second);
								} catch (NumberFormatException e) {
									System.out.println("Invalid Input");
									continue;
								}
								mathObjs2[i][j] = new ComplexNumber(re, im);
							} else {
								double d;
								try {
									d = Double.parseDouble(temp);
								} catch (NumberFormatException e) {
									System.out.println("Invalid Input");
									continue;
								}
								mathObjs2[i][j] = new ComplexNumber(d, 0);
							}
						}
					}
				}
				matrix = new ExtendedMatrix(mathObjs, mathObjs2);
			} else {
				matrix = new Matrix(mathObjs);
			}

			Gausian gausian = new Gausian(matrix);

			System.out.print("Verbose? 'yes'> ");
			System.out.flush();
			temp = in.readLine();
			System.out.println();
			Matrix result = null;
			long start = System.nanoTime();
			if (temp.equals("yes")) {
				result = gausian.solve(2, false);
			} else {
				result = gausian.solve();
			}
			String time = String.format("%.2f",
					(System.nanoTime() - start) / 1000000.0);

			System.out.println("Solution (" + time + "ms)");
			System.out.println(result.toString());

			System.out.print("Exit? 'yes'> ");
			System.out.flush();
			cmd = in.readLine();
		}
	}
}
